package cn.bigfire.wedesk.net.codec;

import cn.bigfire.wedesk.bean.Wedesk;
import cn.bigfire.wedesk.net.protocol.Protocol;
import cn.bigfire.wedesk.net.protocol.TypeMapper;
import cn.bigfire.wedesk.util.ByteUtil;
import cn.bigfire.wedesk.util.ProtostuffUtil;
import cn.hutool.core.util.NumberUtil;
import com.alibaba.fastjson.JSON;
import com.google.protobuf.AbstractMessage;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageEncoder;
import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;

import java.util.List;

/**
 * 业务层 编解码器
 */
public class ProtocolWebSocketEncoder extends MessageToMessageEncoder<Protocol> {

    boolean isJson = true;//控制写数据时使用protobuf还是json

    @Override
    protected void encode(ChannelHandlerContext ctx, Protocol msg, List<Object> out) throws Exception {
        try {
            Protocol protocol = (Protocol) msg;
            if (isJson && protocol.getCmd() != Wedesk.Cmd.CMD_SCREENSHOT_DATA.getValue()) {
                String jsonString = JSON.toJSONString(protocol);
//                System.out.printf("->cmd:%s,type:%s,len:%s[%s]%n", protocol.getCmd(), protocol.getType(), jsonString.length(), ByteUtil.size(jsonString.length()));
                if (protocol.getCmd() != Wedesk.Cmd.CMD_SCREENSHOT_DATA.getValue()) {
                    System.out.printf("->cmd:%s,type:%s,len:%s[%s]%n", protocol.getCmd(), protocol.getType(), jsonString.length(), ByteUtil.size(jsonString.length()));
                }
                TextWebSocketFrame textWebSocketFrame = new TextWebSocketFrame(jsonString);
                out.add(textWebSocketFrame);
            } else {
                int cmd = protocol.getCmd();
                int type = TypeMapper.getType(protocol.getObj().getClass());
                protocol.setType(type);
                byte[] bytes = new byte[0];
                if (protocol.getObj() instanceof AbstractMessage) {
                    AbstractMessage abstractMessage = (AbstractMessage) protocol.getObj();
                    bytes = abstractMessage.toByteArray();
                } else if (protocol.getObj() instanceof byte[]) {
                    bytes = (byte[]) protocol.getObj();
                } else {
                    if (protocol.getType() == Wedesk.Type.TYPE_ScreensHot.getValue()) {
                        if (protocol.getObj() instanceof Wedesk.ScreensHot) {
                            Wedesk.ScreensHot screensHot = (Wedesk.ScreensHot)protocol.getObj();
                            byte[] widthBytes = NumberUtil.toBytes(screensHot.getWidth());
                            byte[] heightBytes = NumberUtil.toBytes(screensHot.getHeight());
                            bytes = ByteUtil.appends(widthBytes, heightBytes, screensHot.getData());
                        }
                    }else {
                        bytes = ProtostuffUtil.serializer(protocol.getObj());
                    }
                }
                ByteBuf outBuf = Unpooled.buffer();
                outBuf.writeInt(cmd);
                outBuf.writeInt(type);
                outBuf.writeBytes(bytes);
                if (protocol.getCmd() != Wedesk.Cmd.CMD_SCREENSHOT_DATA.getValue()){
                    System.out.printf("->cmd:%s,type:%s,len:%s[%s]%n", protocol.getCmd(), protocol.getType(), bytes.length, ByteUtil.size(bytes.length));
                }
//                System.out.printf("->cmd:%s,type:%s,len:%s[%s]%n", protocol.getCmd(), protocol.getType(), bytes.length, ByteUtil.size(bytes.length));
                BinaryWebSocketFrame binaryWebSocketFrame = new BinaryWebSocketFrame(outBuf);
                out.add(binaryWebSocketFrame);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
